<?php
// +----------------------------------------------------------------------
// | INPHP
// | Copyright (c) 2023 https://inphp.cc All rights reserved.
// | Licensed ( https://opensource.org/licenses/MIT )
// | Author: 幺月儿(https://gitee.com/lulanyin) Email: inphp@qq.com
// +----------------------------------------------------------------------
// | 中间键
// +----------------------------------------------------------------------
namespace Inphp\Core;

class Middlewares
{
    /**
     * 中间键列表
     * @var array
     */
    public static array $list = [];

    /**
     * 添加中间键
     * @param string|array $name        常规使用中间键名称字符串，也可以直接加载一个列表进来
     * @param mixed|null $middleware    常规使用中间键回调的方法
     * @param bool $once                是否属于一次性中间键
     */
    public static function push(string|array $name, mixed $middleware = null, bool $once = false) {
        //一次性加载一组
        if (is_array($name)) {
            foreach ($name as $key => $value) {
                self::push($key, $value, true === $middleware || false === $middleware ? $middleware : $once);
            }
            return;
        }
        //正常加载
        if (!isset(self::$list[$name])) {
            self::$list[$name] = [];
        }
        if (empty($middleware)) {
            return;
        }
        //如果是一个列表
        $middleware = is_array($middleware) ? $middleware : [$middleware];
        foreach ($middleware as $m) {
            self::$list[$name][] = [
                "callback"  => $m,
                "once"      => $once
            ];
        }
    }

    /**
     * 获取中间键
     * @param string $name
     * @return array
     */
    public static function get(string $name): array
    {
        return self::$list[$name] ?? [];
    }

    /**
     * 中间键处理
     * @param string $name
     * @param $args
     * @return array
     */
    public static function process(string $name, $args): array {
        $middlewares = self::get($name);
        $result = [];
        $list = [];
        foreach ($middlewares as $middleware) {
            if (is_array($middleware["callback"]) || $middleware["callback"] instanceof \Closure || function_exists($middleware['callback'])) {
                $result[] = call_user_func_array($middleware["callback"], $args);
                if (!$middleware["once"]) {
                    //一次性中间键
                    $list[] = $middleware;
                }
            }
        }
        self::$list[$name] = $list;
        return $result;
    }
}